<template>
  <div class="grid-dashboard">
    <div class="dashboard-title">
      <h1>实时监控数据分析平台</h1>
      <div class="time-info">当前时间: {{ currentTime }}</div>
    </div>

    <div class="grid-container">
      <!-- 第一行 -->
      <div class="grid-item item-1">
        <h3>系统运行状态</h3>
        <div ref="systemStatusChart" class="chart-box"></div>
      </div>

      <div class="grid-item item-2">
        <h3>核心性能指标</h3>
        <div class="kpi-grid">
          <div class="kpi-item">
            <p>CPU使用率</p>
            <p class="kpi-num">{{ cpuUsage }}%</p>
            <div class="progress-bar">
              <div
                class="progress"
                :style="{ width: cpuUsage + '%', backgroundColor: cpuColor }"
              ></div>
            </div>
          </div>
          <div class="kpi-item">
            <p>内存使用率</p>
            <p class="kpi-num">{{ memoryUsage }}%</p>
            <div class="progress-bar">
              <div
                class="progress"
                :style="{ width: memoryUsage + '%', backgroundColor: memoryColor }"
              ></div>
            </div>
          </div>
          <div class="kpi-item">
            <p>网络流量</p>
            <p class="kpi-num">{{ networkTraffic }} MB/s</p>
            <div class="progress-bar">
              <div
                class="progress"
                :style="{ width: networkUsage + '%', backgroundColor: networkColor }"
              ></div>
            </div>
          </div>
          <div class="kpi-item">
            <p>在线用户</p>
            <p class="kpi-num">{{ onlineUsers }}</p>
            <div class="progress-bar">
              <div
                class="progress"
                :style="{ width: userUsage + '%', backgroundColor: userColor }"
              ></div>
            </div>
          </div>
        </div>
      </div>

      <div class="grid-item item-3">
        <h3>全国节点分布</h3>
        <div ref="nodeDistributionMap" class="chart-box"></div>
      </div>

      <!-- 第二行 -->
      <div class="grid-item item-4">
        <h3>请求响应时间趋势</h3>
        <div ref="responseTimeChart" class="chart-box"></div>
      </div>

      <div class="grid-item item-5">
        <h3>全球访问热力图</h3>
        <div ref="worldHeatMap" class="chart-box"></div>
      </div>

      <!-- 第三行 -->
      <div class="grid-item item-6">
        <h3>错误类型分布</h3>
        <div ref="errorTypeChart" class="chart-box"></div>
      </div>

      <div class="grid-item item-7">
        <h3>服务调用统计</h3>
        <div ref="serviceCallChart" class="chart-box"></div>
      </div>

      <div class="grid-item item-8">
        <h3>最近告警</h3>
        <div class="alert-list">
          <div
            v-for="alert in systemAlerts"
            :key="alert.id"
            class="alert-entry"
            :class="alert.level"
          >
            <div class="alert-icon">{{ alert.icon }}</div>
            <div class="alert-content">
              <p class="alert-title">{{ alert.title }}</p>
              <p class="alert-time">{{ alert.time }}</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
  import { ref, onMounted, watch } from 'vue'
  import * as echarts from 'echarts'
  import chinaGeo from '@/assets/map/map.json'
  // import worldGeo from '../assets/world.json'

  // 数据状态
  const currentTime = ref(new Date().toLocaleString())
  const cpuUsage = ref(68)
  const memoryUsage = ref(72)
  const networkTraffic = ref(185)
  const networkUsage = ref(65)
  const onlineUsers = ref(12580)
  const userUsage = ref(45)

  // 动态计算颜色
  const cpuColor = ref('')
  const memoryColor = ref('')
  const networkColor = ref('')
  const userColor = ref('')

  // 告警列表
  const systemAlerts = ref([
    { id: 1, title: '服务器CPU使用率过高', time: '10:23', level: 'critical', icon: '!' },
    { id: 2, title: '华东节点响应延迟', time: '09:45', level: 'warning', icon: '!' },
    { id: 3, title: '数据库连接数接近阈值', time: '08:17', level: 'warning', icon: '!' },
    { id: 4, title: '磁盘空间不足', time: '07:52', level: 'critical', icon: '!' },
    { id: 5, title: '备份任务完成', time: '06:30', level: 'info', icon: '✓' }
  ])

  // 图表引用
  const systemStatusChart = ref(null)
  const nodeDistributionMap = ref(null)
  const responseTimeChart = ref(null)
  const worldHeatMap = ref(null)
  const errorTypeChart = ref(null)
  const serviceCallChart = ref(null)

  // 计算状态颜色
  watch([cpuUsage, memoryUsage, networkUsage, userUsage], () => {
    cpuColor.value = getStatusColor(cpuUsage.value)
    memoryColor.value = getStatusColor(memoryUsage.value)
    networkColor.value = getStatusColor(networkUsage.value)
    userColor.value = getStatusColor(userUsage.value)
  })

  // 初始化图表
  onMounted(() => {
    // 每秒更新时间
    setInterval(() => {
      currentTime.value = new Date().toLocaleString()
    }, 1000)

    // 初始化图表
    echarts.registerMap('china', chinaGeo)
    // echarts.registerMap('world', worldGeo)

    // initSystemStatusChart()
    // initNodeDistributionMap()
    initResponseTimeChart()
    // initWorldHeatMap()
    initErrorTypeChart()
    initServiceCallChart()

    // 模拟数据更新
    setInterval(updateMockData, 5000)
  })

  // 模拟数据更新
  const updateMockData = () => {
    cpuUsage.value = Math.min(95, Math.max(30, cpuUsage.value + (Math.random() * 10 - 5)))
    memoryUsage.value = Math.min(95, Math.max(40, memoryUsage.value + (Math.random() * 8 - 4)))
    networkTraffic.value = Math.min(
      300,
      Math.max(50, networkTraffic.value + (Math.random() * 30 - 15))
    )
    networkUsage.value = Math.min(90, Math.max(30, networkUsage.value + (Math.random() * 8 - 4)))
    onlineUsers.value = Math.min(
      20000,
      Math.max(5000, onlineUsers.value + (Math.random() * 1000 - 500)) | 0
    )
  }

  // 根据百分比获取状态颜色
  const getStatusColor = (value) => {
    if (value < 50) return '#91cc75' // 绿色
    if (value < 80) return '#fac858' // 黄色
    return '#ee6666' // 红色
  }

  // 初始化系统状态图表
  const initSystemStatusChart = () => {
    const chart = echarts.init(systemStatusChart.value)
    chart.setOption({
      tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
      legend: { data: ['正常', '警告', '错误'], textStyle: { color: '#fff' } },
      grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
      xAxis: {
        type: 'category',
        data: ['服务A', '服务B', '服务C', '服务D', '服务E', '服务F'],
        axisLine: { lineStyle: { color: '#4c5464' } }
      },
      yAxis: { type: 'value', axisLine: { lineStyle: { color: '#4c5464' } } },
      series: [
        {
          name: '正常',
          type: 'bar',
          stack: 'total',
          emphasis: { focus: 'series' },
          data: [120, 132, 101, 134, 90, 230],
          itemStyle: { color: '#91cc75' }
        },
        {
          name: '警告',
          type: 'bar',
          stack: 'total',
          emphasis: { focus: 'series' },
          data: [30, 20, 40, 70, 100, 50],
          itemStyle: { color: '#fac858' }
        },
        {
          name: '错误',
          type: 'bar',
          stack: 'total',
          emphasis: { focus: 'series' },
          data: [10, 5, 20, 15, 30, 10],
          itemStyle: { color: '#ee6666' }
        }
      ]
    })
  }

  // 初始化节点分布地图
  const initNodeDistributionMap = () => {
    const chart = echarts.init(nodeDistributionMap.value)
    chart.setOption({
      tooltip: { trigger: 'item' },
      series: [
        {
          name: '服务器节点',
          type: 'map',
          map: 'china',
          roam: false,
          label: { show: true, color: '#fff' },
          data: [
            { name: '北京', value: 35 },
            { name: '上海', value: 42 },
            { name: '广州', value: 28 },
            { name: '深圳', value: 31 },
            { name: '杭州', value: 25 },
            { name: '成都', value: 18 },
            { name: '武汉', value: 15 },
            { name: '西安', value: 12 }
          ],
          itemStyle: { areaColor: '#1e293b', borderColor: '#334155' },
          emphasis: { itemStyle: { areaColor: '#36cbcb' } }
        },
        {
          name: '节点数量',
          type: 'scatter',
          coordinateSystem: 'geo',
          data: [
            { name: '北京', value: [116.4074, 39.9042, 35] },
            { name: '上海', value: [121.4737, 31.2304, 42] },
            { name: '广州', value: [113.2644, 23.1291, 28] },
            { name: '深圳', value: [114.0579, 22.5431, 31] },
            { name: '杭州', value: [120.1551, 30.2741, 25] }
          ],
          symbolSize: function (val) {
            return val[2] / 3
          },
          label: { show: false },
          itemStyle: { color: '#ee6666' }
        }
      ]
    })
  }

  // 初始化响应时间图表
  const initResponseTimeChart = () => {
    const chart = echarts.init(responseTimeChart.value)
    chart.setOption({
      tooltip: { trigger: 'axis' },
      legend: { data: ['平均响应时间', '最大响应时间'], textStyle: { color: '#fff' } },
      grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: ['00:00', '03:00', '06:00', '09:00', '12:00', '15:00', '18:00', '21:00'],
        axisLine: { lineStyle: { color: '#4c5464' } }
      },
      yAxis: {
        type: 'value',
        name: '毫秒(ms)',
        axisLine: { lineStyle: { color: '#4c5464' } },
        splitLine: { lineStyle: { color: 'rgba(76, 84, 100, 0.3)' } }
      },
      series: [
        {
          name: '平均响应时间',
          type: 'line',
          data: [85, 78, 65, 92, 156, 189, 165, 132],
          lineStyle: { color: '#36cbcb' },
          symbol: 'circle',
          symbolSize: 6,
          itemStyle: { color: '#36cbcb' }
        },
        {
          name: '最大响应时间',
          type: 'line',
          data: [156, 142, 128, 185, 268, 320, 285, 220],
          lineStyle: { color: '#ee6666' },
          symbol: 'circle',
          symbolSize: 6,
          itemStyle: { color: '#ee6666' }
        }
      ]
    })
  }

  // 初始化世界热力图
  const initWorldHeatMap = () => {
    const chart = echarts.init(worldHeatMap.value)
    chart.setOption({
      tooltip: { formatter: '{b}: {c}' },
      visualMap: {
        min: 0,
        max: 1000,
        calculable: true,
        inRange: { color: ['#5470c6', '#36cbcb', '#fac858', '#ee6666'] },
        textStyle: { color: '#fff' }
      },
      series: [
        {
          name: '访问量',
          type: 'map',
          map: 'world',
          roam: false,
          label: { show: false },
          data: [
            { name: 'China', value: 850 },
            { name: 'United States', value: 920 },
            { name: 'Japan', value: 450 },
            { name: 'Germany', value: 320 },
            { name: 'United Kingdom', value: 280 },
            { name: 'France', value: 220 },
            { name: 'India', value: 380 }
          ],
          itemStyle: { areaColor: '#1e293b', borderColor: '#334155' }
        }
      ]
    })
  }

  // 初始化错误类型图表
  const initErrorTypeChart = () => {
    const chart = echarts.init(errorTypeChart.value)
    chart.setOption({
      tooltip: { trigger: 'item' },
      legend: { top: 'bottom', textStyle: { color: '#fff' } },
      series: [
        {
          name: '错误类型',
          type: 'pie',
          radius: ['40%', '70%'],
          center: ['50%', '40%'],
          data: [
            { value: 35, name: '连接超时' },
            { value: 25, name: '数据错误' },
            { value: 20, name: '权限不足' },
            { value: 15, name: '参数错误' },
            { value: 5, name: '其他错误' }
          ],
          color: ['#ee6666', '#fac858', '#5470c6', '#36cbcb', '#73c0de']
        }
      ]
    })
  }

  // 初始化服务调用图表
  const initServiceCallChart = () => {
    const chart = echarts.init(serviceCallChart.value)
    chart.setOption({
      tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
      grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
      xAxis: { type: 'value', axisLine: { lineStyle: { color: '#4c5464' } } },
      yAxis: {
        type: 'category',
        data: ['认证服务', '用户服务', '订单服务', '支付服务', '商品服务', '搜索服务', '推荐服务'],
        axisLine: { lineStyle: { color: '#4c5464' } }
      },
      series: [
        {
          name: '调用次数',
          type: 'bar',
          data: [12500, 38200, 25600, 18900, 42300, 36800, 22400],
          itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
              { offset: 0, color: '#5470c6' },
              { offset: 1, color: '#36cbcb' }
            ])
          },
          label: { show: true, position: 'right', color: '#fff' }
        }
      ]
    })
  }

  // 窗口大小变化时重绘图表
  window.addEventListener('resize', () => {
    echarts.getInstanceByDom(systemStatusChart.value)?.resize()
    echarts.getInstanceByDom(nodeDistributionMap.value)?.resize()
    echarts.getInstanceByDom(responseTimeChart.value)?.resize()
    echarts.getInstanceByDom(worldHeatMap.value)?.resize()
    echarts.getInstanceByDom(errorTypeChart.value)?.resize()
    echarts.getInstanceByDom(serviceCallChart.value)?.resize()
  })
</script>

<style scoped>
  .grid-dashboard {
    width: 100%;
    height: 100%;
    background-color: #0f172a;
    color: #fff;
    padding: 1rem;
    box-sizing: border-box;
  }

  .dashboard-title {
    text-align: center;
    margin-bottom: 1rem;
    padding: 0.5rem 0;
  }

  .time-info {
    font-size: 0.9rem;
    color: #94a3b8;
    margin-top: 0.5rem;
  }

  .grid-container {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    grid-template-rows: repeat(3, 1fr);
    gap: 1rem;
    height: calc(100% - 80px);
  }

  .grid-item {
    background-color: #1e293b;
    border-radius: 8px;
    padding: 1rem;
    position: relative;
    overflow: hidden;
  }

  .grid-item h3 {
    margin: 0 0 1rem 0;
    color: #e2e8f0;
    font-size: 1rem;
    display: flex;
    align-items: center;
  }

  .grid-item h3::before {
    content: '';
    display: inline-block;
    width: 4px;
    height: 16px;
    background-color: #36cbcb;
    margin-right: 8px;
    border-radius: 2px;
  }

  .chart-box {
    width: 100%;
    height: calc(100% - 30px);
  }

  /* 网格布局定义 */
  .item-1 {
    grid-column: span 4;
    grid-row: span 1;
  }
  .item-2 {
    grid-column: span 4;
    grid-row: span 1;
  }
  .item-3 {
    grid-column: span 4;
    grid-row: span 1;
  }
  .item-4 {
    grid-column: span 5;
    grid-row: span 1;
  }
  .item-5 {
    grid-column: span 7;
    grid-row: span 1;
  }
  .item-6 {
    grid-column: span 3;
    grid-row: span 1;
  }
  .item-7 {
    grid-column: span 5;
    grid-row: span 1;
  }
  .item-8 {
    grid-column: span 4;
    grid-row: span 1;
  }

  /* KPI指标样式 */
  .kpi-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(2, 1fr);
    gap: 1rem;
    height: calc(100% - 30px);
  }

  .kpi-item {
    background-color: rgba(30, 41, 59, 0.5);
    border-radius: 6px;
    padding: 0.8rem;
  }

  .kpi-item p {
    margin: 0 0 0.5rem 0;
    font-size: 0.9rem;
    color: #94a3b8;
  }

  .kpi-num {
    font-size: 1.5rem;
    font-weight: bold;
    color: #fff;
    margin-bottom: 0.5rem !important;
  }

  .progress-bar {
    height: 6px;
    background-color: #334155;
    border-radius: 3px;
    overflow: hidden;
  }

  .progress {
    height: 100%;
    transition: width 1s ease;
  }

  /* 告警列表样式 */
  .alert-list {
    height: calc(100% - 30px);
    overflow-y: auto;
    padding-right: 0.5rem;
  }

  .alert-entry {
    display: flex;
    align-items: flex-start;
    padding: 0.8rem 0;
    border-bottom: 1px solid #334155;
    gap: 0.8rem;
  }

  .alert-entry:last-child {
    border-bottom: none;
  }

  .alert-icon {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background-color: #334155;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
  }

  .alert-content {
    flex: 1;
  }

  .alert-title {
    margin: 0 0 0.2rem 0;
    font-weight: 500;
  }

  .alert-time {
    margin: 0;
    font-size: 0.8rem;
    color: #94a3b8;
  }

  .critical .alert-icon {
    background-color: #ee6666;
  }
  .warning .alert-icon {
    background-color: #fac858;
  }
  .info .alert-icon {
    background-color: #36cbcb;
  }

  /* 滚动条样式 */
  .alert-list::-webkit-scrollbar {
    width: 4px;
  }
  .alert-list::-webkit-scrollbar-track {
    background: #1e293b;
  }
  .alert-list::-webkit-scrollbar-thumb {
    background: #334155;
    border-radius: 2px;
  }
</style>
